﻿using System;
using System.Windows.Forms;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Deployment;

using COB.SharePoint.Utilities.DeploymentWizard.Core;

namespace COB.SharePoint.Utilities.DeploymentWizard.UI
{
    /// <summary>
    /// Browse dialog for choosing an import parent target location
    /// </summary>
    public partial class frmWebListBrowse : Form
    {
        SPSite siteCollection = null;
        SiteTreeNavigator browseNavigator = null;
        private string m_selectedUrl; // for now we're just selecting one parent
        private int m_nErrors = 0;

        // Properties
        // caller can set these for initial display
        // caller checks these after form closes to see user's choices
        public string SelectedUrl { get { return m_selectedUrl; } set { m_selectedUrl = value; } }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="site"></param>
        public frmWebListBrowse(SPSite site)
        {
            InitializeComponent();

            siteCollection = site;

            browseNavigator = new SiteTreeNavigator(treeView);
            browseNavigator.DisplayLists = SiteTreeNavigator.DisplayListsSetting.DisplayLists;
            browseNavigator.DisplayItems = SiteTreeNavigator.DisplayItemsSetting.NoDisplayItems;
            browseNavigator.OnDisplayNode += addContextMenuToTreeViewNode;
            // TODO: What about this? (to filter system lists) browseNavigator.OnDisplayList += On?DisplayList;

            LoadTree();
        }

        public void LoadTree()
        {
            treeView.Nodes.Clear();
            // TODO -- treeView.ImageList = f_imageList;

            treeView.BeforeExpand += new TreeViewCancelEventHandler(treeView_BeforeExpand);
            try
            {
                using (ActBusy busy = new ActBusy(this))
                {
                    browseNavigator.AddNodesForWeb(siteCollection.RootWeb);
                    treeView.Nodes[0].Expand();
                }
            }
            catch (UnauthorizedAccessException exc)
            {
                DisplayError("Attempting to list site nodes", exc);
                MessageBox.Show(
                    "Unable to list site nodes - the current user is not a site collection administrator for this site.\n\n" +
                    "Please restart the Wizard using a user which has appropriate permissions.",
                    "Insufficient permissions", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception exc)
            {
                DisplayError("Listing site nodes", exc);
            }
        }

        void treeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            // get reference to site, web, list etc..
            SPObjectData objectData = (SPObjectData)e.Node.Tag;

            if (objectData.ObjectType != SPDeploymentObjectType.Site)
            {
                using (ActBusy busy = new ActBusy(this))
                {
                    try
                    {
                        browseNavigator.PopulateObjectChildNodes(e.Node, objectData);
                    }
                    catch (Exception exc)
                    {
                        DisplayError("Expanding node: " + objectData.Url, exc);
                    }
                }
            }
        }
        /// <summary>
        /// Handles click event of context menu item.
        /// Adds item to the listview of items selected for export
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void contextMenuSubItem_Click(object sender, EventArgs e)
        {
            ToolStripItem menuItem = (ToolStripItem)sender;
            SPObjectData objectData = browseNavigator.GetObjectFromContextMenuItem(menuItem);
            addItemToParentListView(objectData);
            m_selectedUrl = objectData.Url;
            DialogResult = DialogResult.OK;
            this.Close();
        }
        private void addItemToParentListView(SPObjectData objectData)
        {
            lstImportParents.Items.Add(getListViewItemFromObjectData(objectData));
        }

        private ListViewItem getListViewItemFromObjectData(SPObjectData objectData)
        {
            string sItemTitle = ((objectData.ObjectType == SPDeploymentObjectType.ListItem) ||
                (objectData.ObjectType == SPDeploymentObjectType.File) ||
                (objectData.ObjectType == SPDeploymentObjectType.Folder)) ?
                objectData.Title : objectData.Url;
            ListViewItem listItem = new ListViewItem(new string[] { sItemTitle, 
                objectData.ObjectType.ToString(), 
                objectData.IncludeDescendents.ToString() });

            listItem.Tag = objectData;
            return listItem;
        }

        private void addContextMenuToTreeViewNode(TreeNode node, SPObjectData objectData)
        {
            ContextMenuStrip ctxtMenu = new ContextMenuStrip();
            ctxtMenu.Items.AddRange(getContextMenuItemsForNode(node, objectData));
            node.ContextMenuStrip = ctxtMenu;
        }

        private ToolStripMenuItem[] getContextMenuItemsForNode(TreeNode node, SPObjectData objectData)
        {
            ToolStripMenuItem menuItem = new ToolStripMenuItem("Select as Parent for Import");

            menuItem.Tag = objectData;
            menuItem.Click += new EventHandler(contextMenuSubItem_Click);

            return new ToolStripMenuItem[] { menuItem };
        }

        private void DisplayError(string status, Exception exc)
        {
            if (status.Length > 0 && !status.EndsWith(":"))
            {
                status += ":";
            }
            OutputLine(status);
            OutputLine("\t" + exc.Message);
            ++m_nErrors;
            grpErrors.Text = string.Format("Errors ({0})", m_nErrors);
            grpErrors.Enabled = true;
        }
        private void OutputLine(string text)
        {
            TextBoxUtil.AppendLineAndScroll(txtErrors, text);
        }

        private void frmWebListBrowse_FormClosed(object sender, FormClosedEventArgs e)
        {
            browseNavigator.DisposeAllWebs();
        }

        // Handle busy display for form (hourglass and waiting message label)
        class ActBusy : IDisposable
        {
            private Cursor m_oldCursor = null;
            private frmWebListBrowse m_form = null;
            public ActBusy(frmWebListBrowse form)
                : this(form, Cursors.WaitCursor)
            {
            }
            public ActBusy(frmWebListBrowse form, Cursor cursor)
            {
                m_form = form;
                StartBusy(cursor);
            }

            private void StartBusy(Cursor cursor)
            {
                m_oldCursor = m_form.Cursor;
                m_form.Cursor = cursor;
                m_form.lblRetrievingData.Visible = true;
            }
            private void EndBusy()
            {
                m_form.Cursor = m_oldCursor;
                m_form.lblRetrievingData.Visible = false;
                m_oldCursor = null;
            }
            public void Dispose()
            {
                if (m_oldCursor != null)
                {
                    EndBusy();
                }
            }
        }
    }
}
